<script setup lang="ts">
import { ref, computed, nextTick } from "vue";
import { trademarkList } from "@/api/product/trademark";
import type { TrademarkData } from "@/api/product/trademark/type";
import {
  getSpuImageList,
  getSpuSaleAttrList,
  getBaseSaleAttrList,
  saveOrUpdateSpu,
} from "@/api/product/spu";
import type {
  SpuData,
  baseSaleAttr,
  SpuImage,
  SpuSaleAttr,
} from "@/api/product/spu/type";
import type { UploadProps } from "element-plus";
import { ElMessage } from "element-plus";
//spu数据
let spuData = ref<SpuData>({
  category3Id: undefined,
  description: "",
  spuImageList: [],
  spuName: "",
  spuSaleAttrList: [],
  tmId: undefined,
});
//自定义事件
const emit = defineEmits(["changeScene"]);
//SPU品牌列表
let tmList = ref<TrademarkData[]>([]);
//SPU基础销售属性列表
let baseSaleAttrList = ref<baseSaleAttr[]>([]);
//SPU图片数据
let spuImageList = ref<SpuImage[]>([]);
//SPU销售属性数据
let spuSaleAttrList = ref<SpuSaleAttr[]>([]);
//图片上传
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
//收集还未选择的销售属性id与name
let unSelectedSaleAttrId = ref<string>("");
//准备一个数组，存放多个组建实例
let inputCompArr = ref<any>([]);
//获取SPU品牌列表
const reqTrademarkList = async () => {
  const res = await trademarkList();
  if (res.code === 200) {
    tmList.value = res.data;
  }
};
//获取SPU图片列表
const reqSpuImageList = async (spuId: number | undefined) => {
  const res = await getSpuImageList(spuId);
  if (res.code === 200) {
    spuImageList.value = res.data.map((item) => {
      return {
        id: item.id,
        name: item.imgName,
        url: item.imgUrl,
        spuId: item.spuId,
      };
    });
  }
};
//获取SPU销售属性列表
const reqSpuSaleAttrList = async (spuId: number | undefined) => {
  const res = await getSpuSaleAttrList(spuId);
  if (res.code === 200) {
    spuSaleAttrList.value = res.data;
  }
};
//获取SPU基础销售属性列表
const reqBaseSaleAttrList = async () => {
  const res = await getBaseSaleAttrList();
  if (res.code === 200) {
    baseSaleAttrList.value = res.data;
  }
};
//保存或更新SPU
const reqSaveOrUpdateSpu = async () => {
  //图片数据
  spuData.value.spuImageList = spuImageList.value.map((item: any) => {
    return {
      id: item.id,
      spuId: spuData.value.id,
      imgName: item.name,
      imgUrl: (!item.response && item.response?.data) || item.url,
    };
  });
  //销售属性数据
  //判断spuSaleAttrList下的spuSaleAttrValueList是否为空，如果为空，则不保存
  for (const item of spuSaleAttrList.value) {
    if (item.spuSaleAttrValueList.length === 0) {
      ElMessage.error("存在为空的销售属性");
      return;
    }
  }
  spuData.value.spuSaleAttrList = spuSaleAttrList.value;
  const res = await saveOrUpdateSpu(spuData.value);
  if (res.code === 200) {
    ElMessage({
      type: "success",
      message: "保存成功",
    });
    emit("changeScene", {
      params: spuData.value.id ? "update" : "add",
      num: 1,
    });
  } else {
    ElMessage({
      type: "error",
      message: "保存失败",
    });
  }
};
//初始化页面数据
const initSpuData = (spu: SpuData) => {
  reqSpuImageList(spu.id);
  reqSpuSaleAttrList(spu.id);
  reqTrademarkList();
  reqBaseSaleAttrList();
  spuData.value = spu;
  resetData();
};
//初始化添加页面数据
const initAddSpuData = (category3Id: number) => {
  reqTrademarkList();
  reqBaseSaleAttrList();
  spuData.value = {
    category3Id: category3Id,
    description: "",
    spuImageList: [],
    spuName: "",
    spuSaleAttrList: [],
    tmId: undefined,
  };
  resetData();
};
//初始化当前页面数据
const resetData = () => {
  spuImageList.value = [];
  spuSaleAttrList.value = [];
  unSelectedSaleAttrId.value = "";
  dialogImageUrl.value = "";
  dialogVisible.value = false;
};
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};
const handleBeforeUpload: UploadProps["beforeUpload"] = (rawFile) => {
  //图片类型判断，只能传jpg、jpeg、gif、png类型
  const allowType = ["jpg", "jpeg", "png", "gif"];
  if (!allowType.includes(rawFile.type.split("/")[1])) {
    ElMessage.error("只能传jpg、jpeg、gif、png类型的图片");
    return false;
  }
  if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error("图片大小不能超过 2MB!");
    return false;
  }
  return true;
};
//销售属性添加
const handleAddAttr = () => {
  let attrNameIdArr = unSelectedSaleAttrId.value.split(":");
  let id = parseInt(attrNameIdArr[0]);
  let attrName = attrNameIdArr[1];
  spuSaleAttrList.value.push({
    baseSaleAttrId: id,
    saleAttrName: attrName,
    spuSaleAttrValueList: [],
    spuId: spuData.value.id,
  });
  unSelectedSaleAttrId.value = "";
};
//计算出未选中的销售属性
const unSelectSaleAttr = computed(() => {
  return baseSaleAttrList.value.filter((item) => {
    return !spuSaleAttrList.value.find(
      (item1) => item1.saleAttrName === item.name,
    );
  });
});
//属性值添加切换至编辑状态
const showInput = (row: SpuSaleAttr, $index: number) => {
  row.flag = true;
  row.saleAttrVal = "";
  //使input获取焦点
  nextTick(() => {
    if (inputCompArr.value.length > 0) {
      inputCompArr.value[$index].focus();
    }
  });
};
//销售属性值添加
const handleAddAttrValue = (row: SpuSaleAttr) => {
  //获取属性值数组
  const { baseSaleAttrId, saleAttrVal, saleAttrName } = row;
  if (!saleAttrVal?.trim()) {
    ElMessage.error("属性值不能为空");
    row.flag = false;
    return;
  }
  //重复
  if (
    row.spuSaleAttrValueList.find(
      (item) => item.saleAttrValueName === saleAttrVal,
    )
  ) {
    ElMessage.error("属性值不能重复");
    row.flag = false;
    return;
  }
  row.spuSaleAttrValueList.push({
    baseSaleAttrId: baseSaleAttrId,
    saleAttrValueName: saleAttrVal,
    id: undefined,
    spuId: spuData.value.id,
    saleAttrName: saleAttrName, //属性名
  });
  row.flag = false;
};
//点击取消按钮，触发自定义事件，并传递参数
const cancel = () => {
  emit("changeScene", {
    params: "cancel",
    num: 1,
  });
};
//暴露初始化页面数据方法给父组件调用
defineExpose({
  initSpuData,
  initAddSpuData,
});
</script>

<template>
  <el-form label-width="120px">
    <!-- 表单内容 -->
    <el-form-item label="SPU名称">
      <el-input placeholder="请输入SPU名称" v-model="spuData.spuName" />
    </el-form-item>
    <el-form-item label="SPU品牌">
      <el-select placeholder="请选择SPU品牌" v-model="spuData.tmId">
        <el-option
          v-for="(trademark, index) in tmList"
          :label="trademark.tmName"
          :value="trademark.id"
          :index="index"
        />
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述">
      <el-input
        type="textarea"
        placeholder="请输入SPU描述"
        v-model="spuData.description"
      />
    </el-form-item>
    <el-form-item label="SPU图片">
      <el-upload
        v-model:file-list="spuImageList"
        list-type="picture-card"
        action="/api/admin/product/fileUpload"
        :on-preview="handlePictureCardPreview"
        :before-upload="handleBeforeUpload"
      >
        <el-icon><Plus /></el-icon>
      </el-upload>
      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" />
      </el-dialog>
    </el-form-item>
    <el-form-item label="SPU销售属性">
      <el-select style="width: 240px" v-model="unSelectedSaleAttrId">
        <el-option
          v-for="(item, index) in unSelectSaleAttr"
          :label="item.name"
          :value="`${item.id}:${item.name}`"
          :index="index"
        />
      </el-select>
      <el-button
        style="margin-left: 10px"
        type="primary"
        icon="Plus"
        :disabled="!unSelectedSaleAttrId"
        @click="handleAddAttr"
        >添加销售属性</el-button
      >
      <el-table border style="margin: 10px 0" :data="spuSaleAttrList">
        <!-- 表格内容 -->
        <el-table-column label="序号" type="index" width="80" />
        <el-table-column label="属性名" prop="saleAttrName" />
        <el-table-column label="属性值" prop="spuSaleAttrValueList">
          <template #default="{ row, $index }">
            <el-tag
              v-for="(item, index) in row.spuSaleAttrValueList"
              :key="item.id"
              style="margin: 0 5px"
              :index="index"
              closable
              @close="row.spuSaleAttrValueList.splice(index, 1)"
              >{{ item.saleAttrValueName }}</el-tag
            >
            <!-- inputCompArr收集el-input组件的实例 -->
            <el-input
              :ref="(vc: any) => (inputCompArr[$index] = vc)"
              v-if="row.flag"
              placeholder="请输入属性值"
              size="small"
              v-model="row.saleAttrVal"
              style="width: 100px"
              @blur="handleAddAttrValue(row)"
            />
            <!-- 增加或删除tag -->
            <el-button
              v-else
              style="margin: 0 5px"
              type="primary"
              icon="Plus"
              size="small"
              @click="showInput(row, $index)"
            />
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template #default="{ $index }">
            <el-button
              type="primary"
              icon="Delete"
              size="small"
              @click="spuSaleAttrList.splice($index, 1)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item>
      <el-button
        type="primary"
        @click="reqSaveOrUpdateSpu"
        :disabled="spuSaleAttrList.length <= 0"
        >保存</el-button
      >
      <el-button @click="cancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<style lang="scss" scoped></style>
